﻿using System;
using System.IO;
using System.Text;
using System.Web;
using System.Net;
using System.Web.Security;


public partial class FileTree6 : System.Web.UI.Page
{
	protected DateTime StartTime;
	protected const string GroupListClass = "GroupList";
	protected const string ObjectListClass = "ObjectList";
	protected UserEntry CurentUser;

	protected void Page_Load(object sender, EventArgs e)
	{
		StartTime = System.DateTime.Now;

		if (Request.HttpMethod == "GET")
		{
			//if (Session["logined"] == null) Session["logined"] = false;
			string RequestAction = Request.QueryString["act"];
			switch (RequestAction)
			{
				#region 下载文件
				case "download":
					{
						string path = Server.HtmlDecode(Request.QueryString["path"]);
						if (path != null && path != "")
						{
							string PhysicalPath = MapPath(path);
							bool IsFirefox = (Request.QueryString["IsFirefox"] == "on" ? true : (Request.UserAgent.IndexOf("Firefox") != -1));
							OutPutFile(PhysicalPath, IsFirefox);
						}
						Response.End();
					}
					break;
				case "remotedownload":
					{
						string remoteUrl = Request.QueryString["url"];
						OutPutRemoteFile(remoteUrl);
						Response.End();
					}
					break;
				#endregion
			}
		}
		else if (Request.HttpMethod == "POST" && Request.Url.ToString().Contains(Request.UrlReferrer.ToString().Split('#')[0]))
		{
			//System.Threading.Thread.Sleep(1000);
			string RequestAction = Request["act"];
			switch (RequestAction)
			{
				#region 登录
				case "login":
					CurentUser = CheckAndGetUser(Request["username"], Request["password"]);
					if (CurentUser != null)
					{
						Response.Write("ok:" + CurentUser.UserName + ":" + CurentUser.UserRootPath);
					}
					Response.End();
					break;
				#endregion
				#region 登出
				case "logout":
					Session["logined"] = null;
					Response.Write("ok");
					Response.End();
					break;
				#endregion
			}
			if (Session["Logined"] == null)
			{
				Response.StatusCode = 500;
				Response.Write("请重新登录");
				Response.End();
			}
			else
			{
				switch (RequestAction)
				{
					#region 根据path输出文件和文件夹列表
					case "LoadNode":
						if (Request["id"] == "0")
						{
							string[] drivers = System.Environment.GetLogicalDrives();
							foreach (string str in drivers)
							{
								Response.Write(str + "|" + str + "?");
							}
							Response.Write("*");
						}
						else
						{
							string path = Request["id"];
							putFolders(path);
							Response.Write("*");
							putFiles(path);
						}
						break;
					#endregion
					#region 刷新所有节点
					case "RefreshNodes":
						string[] idstr = Request["ids"].Split('|');
						foreach (string ID in idstr)
						{
							if (ID == "0")
							{
								string[] drivers = System.Environment.GetLogicalDrives();
								foreach (string str in drivers)
								{
									Response.Write(str + "|" + str + "?");
								}
								Response.Write("*");
								Response.Write("\n");
								continue;
							}
							putFolders(ID);
							Response.Write("*");
							putFiles(ID);
							Response.Write("\n");
						}
						break;
					#endregion
					#region 移动文件夹
					case "Move" + GroupListClass:
						{
							try
							{
								if (((UserEntry)Session["Logined"]).UserRootPath == Server.HtmlDecode(Request["sourceName"]))
								{
									Response.StatusCode = 500;
									Response.Write("根目录不可修改！");
								}
								else
								{
									string sourceName = MapPath(Server.HtmlDecode(Request["sourceName"]));
									string newName = MapPath(Server.HtmlDecode(Request["newName"]));
									Directory.Move(sourceName, newName);
								}
							}
							catch (Exception ex)
							{
								Response.StatusCode = 500;
								Response.Write(ex.Message);
							}
							Response.End();
							break;
						}
					#endregion
					#region 移动文件
					case "Move" + ObjectListClass:
						{
							try
							{
								string sourceName = MapPath(Server.HtmlDecode(Request["sourceName"]));
								string newName = MapPath(Server.HtmlDecode(Request["newName"]));
								File.Move(sourceName, newName);
							}
							catch (Exception ex)
							{
								Response.StatusCode = 500;
								Response.Write(ex.Message);
								Response.End();
							}
							break;
						}
					#endregion
					#region 删除文件夹
					case "Delete" + GroupListClass:
						try
						{
							if (((UserEntry)Session["Logined"]).UserRootPath == Server.HtmlDecode(Request["PathName"]))
							{
								Response.StatusCode = 500;
								Response.Write("根目录不可删除！");
							}
							else
							{
								string PathName = MapPath(Request["PathName"]);
								Directory.Delete(PathName, true);
							}
						}
						catch (Exception ex)
						{
							Response.StatusCode = 500;
							Response.Write(ex.Message);
						}
						Response.End();
						break;
					#endregion
					#region 删除文件
					case "Delete" + ObjectListClass:
						try
						{
							string pathName = MapPath(Request["pathName"]);
							File.Delete(pathName);
						}
						catch (Exception ex)
						{
							Response.StatusCode = 500;
							Response.Write(ex.Message);
						}
						Response.End();
						break;
					#endregion
					#region 创建文件夹
					case "Create" + GroupListClass:
						try
						{
							string PathName = MapPath(Request["PathName"]);
							DirectoryInfo newDirectory = Directory.CreateDirectory(PathName);
							Response.Write(newDirectory.FullName);
						}
						catch (Exception ex)
						{
							Response.StatusCode = 500;
							Response.Write(ex.Message);
							Response.End();
						}
						break;
					#endregion
					#region 创建文件
					case "Create" + ObjectListClass:
						try
						{
							string PathName = MapPath(Request["PathName"]);
							File.Create(PathName).Close();
						}
						catch (Exception ex)
						{
							Response.StatusCode = 500;
							Response.Write(ex.Message);
							Response.End();
						}
						break;
					#endregion
					#region 编辑文件
					case "EditFile":
						try
						{
							string PathName = MapPath(Request["PathName"]);
							string CodePage = Request["CodePage"];
							Encoding enc = null;
							short code = 936;
							bool isNum = short.TryParse(CodePage, out code);
							if (isNum)
							{
								try
								{
									enc = Encoding.GetEncoding(code);
								}
								catch
								{
									enc = Encoding.GetEncoding(936);
								}
							}
							else
							{
								try
								{
									enc = Encoding.GetEncoding(CodePage);
								}
								catch
								{
									enc = Encoding.GetEncoding("GB18030");
								}
							}
							EditFile(PathName, enc);
						}
						catch (Exception ex)
						{
							Response.StatusCode = 500;
							Response.Write(ex.Message);
							Response.End();
						}
						break;
					#endregion
					default:
						break;
				}
				Response.End();
			}
		}
		else
		{
			Response.StatusCode = 500;
			Response.End();
		}
	}

	/// <summary>
	/// 输出文件夹
	/// </summary>
	/// <param name="path"></param>
	void putFolders(string path)
	{
		try
		{
			string PhysicalPath = MapPath(path);
			DirectoryInfo theFolder = new DirectoryInfo(PhysicalPath);
			if (theFolder.Exists)
			{
				int sub = MapPath("/").Length - 1;
				foreach (DirectoryInfo nextFolder in theFolder.GetDirectories())
				{
					Response.Write(nextFolder.FullName.Substring(sub).Replace('\\', '/') + "/" + "|" + nextFolder.Name + "?");
				}
			}
		}
		catch (Exception ex)
		{
			Response.StatusCode = 500;
			Response.Write(ex.ToString());
			Response.End();
		}
	}
	void putFiles(string path)
	{
		try
		{
			string PhysicalPath = MapPath(path);
			DirectoryInfo theFolder = new DirectoryInfo(PhysicalPath);
			if (theFolder.Exists)
			{
				int sub = MapPath("/").Length - 1;
				foreach (FileInfo nextFile in theFolder.GetFiles())
				{
					Response.Write(nextFile.FullName.Substring(sub).Replace('\\', '/') + "|" + nextFile.Name + "|" + nextFile.Extension + "?");
				}
			}
		}
		catch (Exception ex)
		{
			Response.StatusCode = 500;
			Response.Write(ex.Message);
			Response.End();
		}
	}

	/// <summary>
	/// 文件下载流
	/// </summary>
	/// <param name="FilePath">文件路径</param>
	/// <returns></returns>
	internal bool OutPutFile(string FilePath, bool IsFirefox)
	{
		Stream stream = null;
		bool flag;
		byte[] buffer = new byte[0x2800];
		string fileName = Path.GetFileName(FilePath);
		try
		{
			stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
			long length = stream.Length;
			long startPosition = 0L;
			if (Request.Headers["Range"] != null)
			{
				Response.StatusCode = 0xce;
				string str2 = base.Request.Headers["Range"].Replace("bytes=", "");
				startPosition = long.Parse(str2.Substring(0, str2.IndexOf("-")));
			}
			if (startPosition != 0L)
			{
				string[] strArray = new string[] { "bytes ", startPosition.ToString(), "-", (length - 1L).ToString(), "/", length.ToString() };
				Response.AddHeader("Content-Range", string.Concat(strArray));
			}
			long leftBytes = length - startPosition;
			Response.AddHeader("Content-Length", leftBytes.ToString());
			Response.ContentType = "application/octet-stream;charset=UTF-8";
			Response.AddHeader("Content-Disposition", "attachment; filename" + (IsFirefox ? "*" : "") + "=" + HttpUtility.UrlEncode(fileName).Replace("+", "%20"));
			stream.Position = startPosition;
			length -= startPosition;
			while (length > 0L)
			{
				if (Response.IsClientConnected)
				{
					int count = stream.Read(buffer, 0, 0x2800);
					Response.OutputStream.Write(buffer, 0, count);
					Response.Flush();
					buffer = new byte[0x2800];
					length -= count;
				}
				else
				{
					length = -1L;
				}
			}
			flag = true;
		}
		catch (Exception exception)
		{
			Response.Write(exception.Message);
			flag = false;
		}
		finally
		{
			if (stream != null)
			{
				stream.Close();
			}
		}
		return flag;
	}
	/// <summary>
	/// 编辑文件
	/// </summary>
	/// <param name="path">文件路径</param>
	/// <param name="encoding">读取文件的编码</param>
	protected internal void EditFile(string path, Encoding encoding)
	{
		Response.ContentType = "text/plain";
		//StreamReader sr = new StreamReader(path, Encoding.Default);
		//string content = sr.ReadToEnd();
		string content = File.ReadAllText(path, encoding);
		//sr.Close();
		//byte[] content_bytes_UTF8 = Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding(936), encoding.GetBytes(content));
		//string Content_UTF8 = Encoding.UTF8.GetString(content_bytes_UTF8);
		Response.Write(content);
	}

	UserEntry CheckAndGetUser(string UserName, string PassWord)
	{
		if (UserName == "admin" && PassWord == "adminer")
		{
			string RootFullPath = Request.ApplicationPath == "/" ? Request.ApplicationPath : Request.ApplicationPath + "/";

			UserEntry User = new UserEntry();
			User.UserName = UserName;
			User.PassWord = PassWord;
			User.UserRootPath = RootFullPath;
			Session["logined"] = User;
			return User;
		}
		if (UserName == "test" && PassWord == "test")
		{
			string RootFullPath = Request.ApplicationPath == "/" ? Request.ApplicationPath : Request.ApplicationPath + "/";
			RootFullPath += "test/";
			if (!Directory.Exists(MapPath(RootFullPath)))
			{
				Directory.CreateDirectory(MapPath(RootFullPath));
			}
			UserEntry User = new UserEntry();
			User.UserName = UserName;
			User.PassWord = PassWord;
			User.UserRootPath = RootFullPath;
			Session["logined"] = User;
			return User;
		}
		return null;
	}
	protected double runTime()
	{
		TimeSpan ts = System.DateTime.Now - StartTime;
		return ts.TotalMilliseconds;
	}

	/// <summary>
	/// 远程文件下载
	/// </summary>
	/// <param name="FilePath">文件路径</param>
	/// <returns></returns>
	internal bool OutPutRemoteFile(string RemoteUrl)
	{
		if (Request.UserAgent.IndexOf("Firefox") != -1)
		{
			RemoteUrl = RemoteUrl + (RemoteUrl.IndexOf('?') == -1 ? "?" : "&") + "IsFirefox=on";
		}
		Stream responseStream = null;

		try
		{
			HttpWebRequest request = (HttpWebRequest)WebRequest.Create(RemoteUrl);
			long startPosition = 0L;
			string range = Request.Headers["Range"];
			if (range != null)
			{
				Response.StatusCode = 0xce;
				string str2 = base.Request.Headers["Range"].Replace("bytes=", "");
				startPosition = long.Parse(str2.Substring(0, str2.IndexOf("-")));
				request.AddRange((int)startPosition);
			}
			HttpWebResponse response = (HttpWebResponse)request.GetResponse();
			if (startPosition != 0L)
			{
				if (response.Headers["Content-Range"] != null)
				{
					Response.AddHeader("Content-Range", response.Headers["Content-Range"]);
				}
				else
				{
					Response.Write("源站点不支持断点下载");
					Response.End();
				}
			}
			Response.ContentType = "application/octet-stream;charset=UTF-8";
			if (response.Headers["Content-Length"] != null)
			{
				Response.AppendHeader("Content-Length", response.Headers["Content-Length"]);
			}
			if (response.Headers["Content-Disposition"] != null)
			{
				Response.AppendHeader("Content-Disposition", response.Headers["Content-Disposition"] + ".___");
			}
			else
			{
				string filename = RemoteUrl.Substring(RemoteUrl.LastIndexOf('/')) + ".___";
				Response.AppendHeader("Content-Disposition", "attachment; filename" + (Request.UserAgent.IndexOf("Firefox") != -1 ? "*" : "") + "=" + HttpUtility.UrlEncode(filename).Replace("+", "%20"));
			}
			long length = response.ContentLength;

			//HttpStatusCode code = response.StatusCode;

			responseStream = response.GetResponseStream();
			byte[] buffer0 = new byte[0x2800];
			while (length > 0)
			{
				if (Response.IsClientConnected)
				{
					int count = responseStream.Read(buffer0, 0, 0x2800);
					Response.OutputStream.Write(buffer0, 0, count);
					Response.Flush();
					buffer0 = new byte[0x2800];
					length -= count;
				}
				else
				{
					length = -1L;
				}
			}
			return true;
		}
		catch (Exception exception)
		{
			Response.Write("下载错误：<br/>");
			Response.Write("地址：" + Server.HtmlEncode(RemoteUrl) + "<br/>");
			Response.Write("原因：" + exception.Message);
			return false;
		}
		finally
		{
			if (responseStream != null)
			{
				responseStream.Close();
			}
		}
	}
}
